package com.magictower.primary.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.StatFs;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.magictower.primary.R;
import com.magictower.primary.adapter.CacheAdapter;
import com.magictower.primary.bean.CacheInfo;
import com.magictower.primary.utils.ToastUtils;

import java.io.File;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author kejunzhan
 * @since 2017/12/22
 */

public class CleanCacheActivity extends AppCompatActivity {

    private ListView list_view;
    private PackageManager pm;
    private List<CacheInfo> cacheInfos;
    private CacheAdapter adapter;
    private ProgressBar pb_progress;
    private TextView tv_desc;
    private int count = 0;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initUI();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        initUI();
    }

    private void initUI() {
        setContentView(R.layout.activity_clean_cache);
        list_view = (ListView) findViewById(R.id.list_view);
        pb_progress = (ProgressBar) findViewById(R.id.pb_progress);
        tv_desc = (TextView) findViewById(R.id.tv_desc);
        pm = getPackageManager();
        //设置进度条可视
        pb_progress.setVisibility(View.VISIBLE);
        tv_desc.setVisibility(View.VISIBLE);
        cacheInfos = new ArrayList<>();
        new Thread() {
            @Override
            public void run() {
                List<PackageInfo> installedPackages = pm.getInstalledPackages(0);
                int size = installedPackages.size();
                pb_progress.setMax(size);
                getCacheList(installedPackages);
                while (true) {
                    //System.out.println("count:" + count + "====" + size);
                    pb_progress.setProgress(count);
                    if (count == size) {
                        handler.sendEmptyMessage(0);
                        return;
                    }
                }
            }
        }.start();
    }

    private Handler handler = new MyHandle(this);

    static class MyHandle extends Handler {
        private WeakReference<CleanCacheActivity> weakReference;

        private MyHandle(CleanCacheActivity context) {
            weakReference = new WeakReference<>(context);
        }

        @Override
        public void handleMessage(Message msg) {
            if (weakReference == null) {
                return;
            }
            CleanCacheActivity activity = weakReference.get();
            activity.pb_progress.setVisibility(View.INVISIBLE);
            activity.tv_desc.setVisibility(View.INVISIBLE);
            activity.adapter = new CacheAdapter(activity, activity.cacheInfos);
            activity.list_view.setAdapter(activity.adapter);
        }
    }

    private void getCacheList(List<PackageInfo> packageInfos) {
        count = 0;
        try {
            //通过反射获取的当前的方法
            Method method = PackageManager.class.getDeclaredMethod("getPackageSizeInfo",
                    String.class, IPackageStatsObserver.class);
            for (PackageInfo info : packageInfos) {
                final PackageInfo packageInfo = info;
                /**
                 * 第一个参数表示当前这个方法的调用
                 * 第二个参数表示包名
                 */
                method.invoke(pm, packageInfo.applicationInfo.packageName, new IPackageStatsObserver.Stub() {
                    @Override
                    public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
                        long cacheSize = pStats.cacheSize;
                        //System.out.println(pStats.packageName + "---" + packageInfo.applicationInfo.packageName);
                        //上述数据相同
                        if (cacheSize > 12 * 1024) {
                            long dataSize = pStats.dataSize;
                            Drawable icon = packageInfo.applicationInfo.loadIcon(pm);
                            String apkName = packageInfo.applicationInfo.loadLabel(pm).toString();
                            CacheInfo cacheInfo = new CacheInfo();
                            cacheInfo.setIcon(icon);
                            cacheInfo.setApkName(apkName);
                            cacheInfo.setCacheSize(cacheSize);
                            cacheInfo.setDataSize(dataSize);
                            cacheInfo.setPackageName(pStats.packageName);
                            cacheInfos.add(cacheInfo);
                        }
                        count++;
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //一键清除缓存
    public void cleanAll(View view) {
        try {
            Method localMethod = pm.getClass().getMethod("freeStorageAndNotify", Long.TYPE, IPackageDataObserver.class);
            Long localLong = getEnvironmentSize() - 1L;
            localMethod.invoke(pm, localLong, new MyPackageDataObserver());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //之前这个方法不能正确清除，是因为申请的内在不足。因此使用上述方法
        //Method[] methods = pm.getClass().getMethods();
        //for (Method method : methods) {
        //    if ("freeStorageAndNotify".equals(method.getName())) {
        //        try {
        //            method.invoke(pm, Integer.MAX_VALUE * 10L, new MyPackageDataObserver());
        //        } catch (Exception e) {
        //            e.printStackTrace();
        //        }
        //    }
        //}
    }

    private class MyPackageDataObserver extends IPackageDataObserver.Stub {
        @Override
        public void onRemoveCompleted(String packageName, final boolean succeeded) throws RemoteException {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (!succeeded) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(CleanCacheActivity.this);
                        builder.setTitle("温馨提示");
                        builder.setMessage("所有应用程序缓存清除完毕！");
                        builder.setPositiveButton("返回", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        });
                        builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                            @Override
                            public void onDismiss(DialogInterface dialog) {
                                initUI();
                            }
                        });
                        builder.show();
                    } else {
                        ToastUtils.showToast(CleanCacheActivity.this, "消除缓存失败，请稍后...");
                    }
                }
            });
        }
    }

    /**
     * 获取data目录下的存储空间大小
     */
    private long getEnvironmentSize() {
        File localFile = Environment.getDataDirectory();
        long res1;
        if (localFile == null) return 0L;
        String str = localFile.getPath();
        //System.out.println("getEnvironmentSizePath: ===="+str);// data
        StatFs localStatFs = new StatFs(str);
        long res2 = localStatFs.getBlockSize();
        res1 = localStatFs.getBlockCount() * res2;
        //System.out.println("getEnvironmentSize: ===="+res1); // 15853404160
        return res1;
    }
}
